import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'storage_service.dart';
import '../api/index.dart';
import '../models/index.dart';
import '../values/constants.dart';
import '../routers/names.dart';

/// 用户服务 - 业务层服务
/// 
/// 🎯 核心职责：
/// - 用户登录/登出业务逻辑
/// - 用户信息管理和验证
/// - 用户权限控制
/// - 用户状态管理
/// - 用户数据持久化
class UserService extends GetxService {
  static UserService get to => Get.find<UserService>();
  
  // ==================== 依赖注入 ====================
  StorageService get _storageService => Get.find<StorageService>();
  
  // ==================== 响应式状态 ====================
  final _isLoggedIn = false.obs;
  final _currentExpertInfo = Rxn<ExpertInfo>();
  final _userToken = ''.obs;
  final _refreshToken = ''.obs;
  
  // ==================== 同步访问器 ====================
  bool get isLoggedIn => _isLoggedIn.value;
  ExpertInfo? get currentExpertInfo => _currentExpertInfo.value;
  String get userToken => _userToken.value;
  String get refreshToken => _refreshToken.value;
  
  // ==================== 响应式访问器 ====================
  RxBool get isLoggedInRx => _isLoggedIn;
  Rxn<ExpertInfo> get currentExpertInfoRx => _currentExpertInfo;
  RxString get userTokenRx => _userToken;
  RxString get refreshTokenRx => _refreshToken;
  
  // ==================== 权限业务逻辑 ====================
  
  /// 检查用户是否有特定权限（专家信息模型简化版）
  bool hasPermission(String permission) {
    // 专家信息模型没有权限相关字段，暂时返回false
    // 可以根据实际需求扩展
    return false;
  }
  
  /// 检查用户是否有特定角色（专家信息模型简化版）
  bool hasRole(String role) {
    // 专家信息模型没有角色相关字段，暂时返回false
    // 可以根据实际需求扩展
    return false;
  }
  
  // ==================== 生命周期 ====================
  @override
  Future<void> onInit() async {
    super.onInit();
    debugPrint('👤 UserService 初始化开始...');
    await _checkLoginStatus();
    debugPrint('✅ UserService 初始化完成');
  }
  
  @override
  void onClose() {
    debugPrint('🧹 UserService 正在清理...');
    super.onClose();
  }
  
  // ==================== 登录相关方法 ====================
  
  /// 发送短信验证码
  Future<bool> sendSMS(String phone) async {
    try {
      debugPrint('📱 开始发送验证码: $phone');
      
      final result = await UserApi.sendSMS(phone);
      
      debugPrint('✅ 验证码发送成功');
      return result;
      
    } catch (e) {
      debugPrint('❌ 验证码发送异常: $e');
      rethrow; // 重新抛出异常，让调用者处理
    }
  }
  
  /// 用户登录（手机号验证码登录）
  Future<LoginResult> login({
    required String phone,
    required String captcha,
  }) async {
    try {
      debugPrint('👤 开始用户登录: $phone');
      
      final tokenModel = await UserApi.login(phone, captcha);
      
      debugPrint('✅ API登录成功，获取到token');
      debugPrint('🔐 AccessToken长度: ${tokenModel.accessToken.length}');
      
      // 保存基础登录信息
      await _saveBasicLoginInfo(tokenModel, phone);
      
      // 尝试获取完整专家信息
      await _fetchAndSaveExpertInfo(tokenModel);
      
      debugPrint('✅ 用户登录成功: $phone');
      return LoginResult.success();
      
    } catch (e) {
      debugPrint('❌ 用户登录异常: $e');
      // 根据错误信息返回更具体的错误
      final errorMessage = e.toString().contains('Exception:') 
          ? e.toString().replaceFirst('Exception: ', '')
          : '网络连接异常，请检查网络后重试';
      return LoginResult.failure(errorMessage);
    }
  }
  
  /// 用户退出登录
  /// 
  /// [navigateToLogin] 是否自动跳转到登录页，默认为false
  Future<bool> logout({bool navigateToLogin = false}) async {
    try {
      debugPrint('👤 用户退出登录');
      
      await _clearAllStorageData();
      _clearUserState();
      
      // 如果需要跳转到登录页
      if (navigateToLogin) {
        debugPrint('🔄 退出登录后自动跳转到登录页');
        _navigateToLogin();
      }
      
      debugPrint('✅ 用户退出登录成功');
      return true;
      
    } catch (e) {
      debugPrint('❌ 用户退出登录失败: $e');
      return false;
    }
  }
  
  /// 刷新访问令牌
  Future<RefreshTokenResult> refreshAccessToken() async {
    try {
      debugPrint('🔄 UserService开始刷新访问令牌');
      
      final currentRefreshToken = _refreshToken.value;
      if (currentRefreshToken.isEmpty) {
        debugPrint('❌ 刷新令牌为空，无法刷新');
        return RefreshTokenResult.failure('刷新令牌不存在');
      }
      
      final tokenModel = await UserApi.refreshToken(currentRefreshToken);
      
      debugPrint('✅ API刷新令牌成功');
      debugPrint('🔄 新AccessToken长度: ${tokenModel.accessToken.length}');
      
      // 更新本地令牌
      await _updateTokens(tokenModel);
      
      return RefreshTokenResult.success(tokenModel);
      
    } catch (e) {
      debugPrint('❌ 刷新令牌异常: $e');
      // 根据错误信息返回更具体的错误
      final errorMessage = e.toString().contains('Exception:') 
          ? e.toString().replaceFirst('Exception: ', '')
          : '刷新令牌过程中发生错误，请重新登录';
      
      // 如果是认证相关错误，自动退出登录并跳转到登录页
      if (errorMessage.contains('令牌') || errorMessage.contains('登录') || errorMessage.contains('JWT expired')) {
        debugPrint('⚠️ 刷新令牌失败，自动退出登录并跳转登录页');
        await logout();
        _navigateToLogin('登录已过期，请重新登录');
      }
      
      return RefreshTokenResult.failure(errorMessage);
    }
  }
  
  // ==================== 专家信息管理 ====================
  
  /// 获取专家信息（对外接口）
  /// 
  /// 从服务器获取最新的专家信息并自动保存到本地
  /// 这是标准的服务层方法，供控制器层调用
  /// 会自动检查登录状态，未登录时抛出异常
  Future<ExpertInfo> getExpertInfo() async {
    try {
      debugPrint('👤 开始获取专家信息');
      
      // ✅ 首先检查登录状态（服务层职责）
      if (!isLoggedIn) {
        debugPrint('❌ 用户未登录，无法获取专家信息');
        throw Exception('用户未登录，请先登录');
      }
      
      debugPrint('✅ 用户已登录，继续获取最新专家信息');
      
      // 调用 API 层获取专家信息
      final expertInfo = await UserApi.getExpertInfo();
      debugPrint('✅ 从服务器获取专家信息成功: ${expertInfo.name}');
      
      // 自动保存到本地
      await setExpertInfo(expertInfo);
      debugPrint('✅ 专家信息已保存到本地');
      
      return expertInfo;
      
    } catch (e) {
      debugPrint('❌ 获取专家信息失败: $e');
      rethrow; // 重新抛出异常，让调用者处理
    }
  }
  
  /// 设置专家信息（核心方法）
  Future<bool> setExpertInfo(ExpertInfo expertInfo) async {
    try {
      debugPrint('👤 设置专家信息: ${expertInfo.name}');
      
      // 更新响应式状态
      _currentExpertInfo.value = expertInfo;
      
      // 保存到本地存储
      await _saveExpertInfoToStorage(expertInfo);
      
      debugPrint('✅ 专家信息设置成功');
      return true;
        
      } catch (e) {
      debugPrint('❌ 设置专家信息失败: $e');
      return false;
    }
  }
  
  // ==================== 数据获取方法 ====================
  

  
  /// 获取最后登录时间
  DateTime? getLastLoginTime() {
    try {
      final timeString = _storageService.getString(Constants.storageKeyLastLoginTime);
      return timeString != null ? DateTime.parse(timeString) : null;
    } catch (e) {
      debugPrint('❌ 获取最后登录时间失败: $e');
      return null;
    }
  }
  
  /// 获取完整的TokenModel
  TokenModel? getTokenModel() {
    try {
      final tokenData = _storageService.getObject(Constants.storageKeyTokenModel);
      return tokenData != null ? TokenModel.fromJson(tokenData) : null;
    } catch (e) {
      debugPrint('❌ 获取TokenModel失败: $e');
      return null;
    }
  }
  
  // ==================== 私有方法 ====================
  
  /// 检查登录状态
  Future<void> _checkLoginStatus() async {
    try {
      final token = _storageService.getString(Constants.storageKeyUserToken) ?? '';
      final refreshToken = _storageService.getString(Constants.storageKeyRefreshToken) ?? '';
      final expertInfoData = _storageService.getObject(Constants.storageKeyExpertInfo);
      
      if (token.isNotEmpty && expertInfoData != null) {
        debugPrint('👤 发现已保存的登录信息');
        
        final expertInfo = ExpertInfo.fromJson(expertInfoData);
        
        _userToken.value = token;
        _refreshToken.value = refreshToken;
        _currentExpertInfo.value = expertInfo;
        _isLoggedIn.value = true;
        
        // 检查登录是否过期
        await _checkLoginExpiration();
      } else {
        debugPrint('👤 未找到登录信息');
        _clearUserState();
      }
      
    } catch (e) {
      debugPrint('❌ 检查登录状态失败: $e');
      _clearUserState();
    }
  }
  
  /// 检查登录过期
  Future<void> _checkLoginExpiration() async {
    try {
      final lastLoginTime = getLastLoginTime();
      if (lastLoginTime != null) {
        final daysSinceLogin = DateTime.now().difference(lastLoginTime).inDays;
        if (daysSinceLogin > Constants.loginExpirationDays) {
          debugPrint('⚠️ 登录信息已过期，自动退出登录');
          await logout();
        }
      }
    } catch (e) {
      debugPrint('❌ 检查登录过期失败: $e');
    }
  }
  
  /// 清除用户状态
  void _clearUserState() {
    _isLoggedIn.value = false;
    _currentExpertInfo.value = null;
    _userToken.value = '';
    _refreshToken.value = '';
  }
  
  /// 保存基础登录信息
  Future<void> _saveBasicLoginInfo(TokenModel tokenModel, String phone) async {
    _userToken.value = tokenModel.accessToken;
    _refreshToken.value = tokenModel.refreshToken;
    _isLoggedIn.value = true;
    
    // 创建基础专家信息
    final basicExpertInfo = ExpertInfo(
      id: 0,
      name: phone,
      corpName: '',
      officialCapacity: '',
      phone: phone,
      email: '',
    );
    _currentExpertInfo.value = basicExpertInfo;
    
    // 保存到存储
    await _storageService.setString(Constants.storageKeyUserToken, tokenModel.accessToken);
    await _storageService.setString(Constants.storageKeyRefreshToken, tokenModel.refreshToken);
    await _storageService.setString(Constants.storageKeyUsername, phone);
    await _storageService.setString(Constants.storageKeyLastLoginTime, DateTime.now().toIso8601String());
    await _storageService.setObject(Constants.storageKeyTokenModel, tokenModel.toJson());
    
    debugPrint('✅ 基础登录信息保存成功');
  }
  
  /// 获取并保存完整专家信息
  Future<void> _fetchAndSaveExpertInfo(TokenModel tokenModel) async {
    try {
      final expertInfo = await UserApi.getExpertInfo();
      debugPrint('✅ 获取到完整专家信息: ${expertInfo.name}');
      
      _currentExpertInfo.value = expertInfo;
      await _saveExpertInfoToStorage(expertInfo);
      
    } catch (e) {
      debugPrint('⚠️ 获取专家详细信息异常，继续使用基础信息: $e');
    }
  }
  
  /// 保存专家信息到存储
  Future<void> _saveExpertInfoToStorage(ExpertInfo expertInfo) async {
    final expertInfoData = {
      ...expertInfo.toJson(),
      'loginTime': DateTime.now().toIso8601String(),
    };
    
    await _storageService.setString(Constants.storageKeyUserId, expertInfo.id.toString());
    await _storageService.setString(Constants.storageKeyUsername, expertInfo.name ?? '');
    await _storageService.setObject(Constants.storageKeyExpertInfo, expertInfoData);
  }
  
  /// 更新令牌
  Future<void> _updateTokens(TokenModel newTokenModel) async {
    _userToken.value = newTokenModel.accessToken;
    _refreshToken.value = newTokenModel.refreshToken;
    
    await _storageService.setString(Constants.storageKeyUserToken, newTokenModel.accessToken);
    await _storageService.setString(Constants.storageKeyRefreshToken, newTokenModel.refreshToken);
    await _storageService.setObject(Constants.storageKeyTokenModel, newTokenModel.toJson());
    
    debugPrint('✅ 令牌更新成功');
  }
  
  /// 清除所有存储数据
  Future<void> _clearAllStorageData() async {
    final keys = [
      Constants.storageKeyUserToken,
      Constants.storageKeyRefreshToken,
      Constants.storageKeyTokenModel,
      Constants.storageKeyUserId,
      Constants.storageKeyUsername,
      Constants.storageKeyExpertInfo,
      Constants.storageKeyLastLoginTime,
    ];
    
    for (final key in keys) {
      await _storageService.remove(key);
    }
    
    debugPrint('✅ 所有存储数据清除成功');
  }
  
  /// 跳转到登录页面
  void _navigateToLogin([String? message]) {
    try {
      debugPrint('🔄 跳转到登录页面');
      if (message != null && message.isNotEmpty) {
        debugPrint('💬 登录提示信息: $message');
      }
      
      // 清除所有路由历史，直接跳转到登录页
      Get.offAllNamed(RouteNames.systemLogin);
      
      // 如果有提示消息，显示SnackBar
      if (message != null && message.isNotEmpty) {
        Get.snackbar(
          '登录提示',
          message,
          snackPosition: SnackPosition.TOP,
          duration: const Duration(seconds: 3),
        );
      }
      
      debugPrint('✅ 跳转到登录页面成功');
    } catch (e) {
      debugPrint('❌ 跳转到登录页面失败: $e');
    }
  }
  
  // ==================== 公开方法 - 对外提供的登录导航接口 ====================
  
  /// 跳转到登录页面（公开方法）
  /// 
  /// [message] 可选的提示消息
  /// 用于其他服务或控制器需要强制用户重新登录时调用
  void navigateToLogin([String? message]) {
    _navigateToLogin(message);
  }
  
  /// 强制退出登录并跳转到登录页
  /// 
  /// [reason] 退出原因，用于显示给用户
  /// 用于token过期、安全问题等场景
  Future<void> forceLogoutAndNavigate([String? reason]) async {
    try {
      debugPrint('🚨 强制退出登录: ${reason ?? "未知原因"}');
      
      // 退出登录但不自动跳转，我们手动控制
      await logout(navigateToLogin: false);
      
      // 手动跳转并显示原因
      final message = reason ?? '登录状态异常，请重新登录';
      _navigateToLogin(message);
      
      debugPrint('✅ 强制退出登录并跳转完成');
      
    } catch (e) {
      debugPrint('❌ 强制退出登录失败: $e');
      // 即使失败也尝试跳转到登录页
      _navigateToLogin('系统错误，请重新登录');
    }
  }
  
  /// 检查Token是否即将过期（主动检查）
  /// 
  /// 返回值：
  /// - true: Token正常或已刷新
  /// - false: Token过期且刷新失败
  Future<bool> checkAndRefreshTokenIfNeeded() async {
    try {
      debugPrint('🔍 主动检查Token状态...');
      
      if (!isLoggedIn) {
        debugPrint('⚠️ 用户未登录，无需检查Token');
        return false;
      }
      
      final tokenModel = getTokenModel();
      if (tokenModel == null) {
        debugPrint('⚠️ 无法获取Token模型');
        return false;
      }
      
      debugPrint('🔍 Token状态: 剩余${tokenModel.remainingExpiresIn}秒');
      
      // 如果Token已过期或即将在2分钟内过期，尝试刷新
      if (tokenModel.isExpired || tokenModel.isExpiringSoon(const Duration(minutes: 2))) {
        debugPrint('🔄 Token即将过期，主动刷新...');
        
        final refreshResult = await refreshAccessToken();
        if (refreshResult.isSuccess) {
          debugPrint('✅ 主动Token刷新成功');
          return true;
        } else {
          debugPrint('❌ 主动Token刷新失败，强制退出登录');
          await forceLogoutAndNavigate('登录已过期，请重新登录');
          return false;
        }
      }
      
      debugPrint('✅ Token状态良好');
      return true;
      
    } catch (e) {
      debugPrint('❌ 检查Token状态异常: $e');
      return false;
    }
  }
  
}
